(function() {
	var hInterval = 100;
	var vInterval = 50;
	var offsetX = 100;
	var offsetY = 100;
	var wfModel = new WfModel();
	var formName = '';

	function getRootLayer(model) {
		return model.getRoot().getChildAt(0);
	}

	function create(model, nodeType, value, x, y) {
		var cell = nodeType.createCell(value, x, y);
		model.add(getRootLayer(model), cell);
		return cell;
	}
	
	function connect(model, source, target) {
		var value = wfModel.getWorkflowTransitionObject();
		value.setAttribute('Name', source.value.getAttribute('Name') + '_' + target.value.getAttribute('Name'));
		value.setAttribute('DisplayName', '');
		var geo = new mxGeometry();
		geo.relative = true;
		var cell = new mxCell(value, geo);
		cell.setEdge(true);
		cell.setTerminal(source, true);
		cell.setTerminal(target, false);
		model.add(getRootLayer(model), cell);
		return cell;
	}
	
	Editor.prototype.createFreeflow = function(config) {
		var value = null;
		var model = this.graph.getModel();
		var start, end, manual;
		var midY = (config.selected.length * 
				(vInterval + this.nodetypes.Manual.height) - vInterval) / 2 - this.nodetypes.Manual.height / 2;
		//var id = Math.uuid();
		
		var workflow = this.graph.getWorkflow();
		workflow.setAttribute('Category', config.categoryId);
		workflow.setAttribute('Id', config.uuid);
		workflow.setAttribute('Name', config.name);
		workflow.setAttribute('Form', formName);
		workflow.setAttribute('DisplayName', config.title);
		workflow.setAttribute('Description', config.description);
//		alert(config.description);
		workflow.setAttribute('DeployTime', new Date().toString("yyyy-MM-dd HH:mm:ss"));
		
		value = wfModel.getWorkflowTokenObject('start');
		value.setAttribute('Form', formName);
		value.setAttribute('DisplayName', "开始");
		var curX = offsetX, curY = offsetY;
		var join, fork,prev;
		
		curX += 0;
		curY += (config.mode == 'S' ? 0 : midY);
		start = create(model, this.nodetypes.Start, value, curX, curY);
		prev = start;
		
		if (config.mode == 'P') {
			value = wfModel.getWorkflowTokenObject('fork');
			curX += this.nodetypes.Start.width + hInterval;
			fork = create(model, this.nodetypes.Fork, value, curX, curY);
			connect(model, start, fork);

			value = wfModel.getWorkflowTokenObject('join');
			curX += this.nodetypes.Fork.width + this.nodetypes.Manual.width + 2 * hInterval;
			join = create(model, this.nodetypes.Join, value, curX, curY);
		}
		
		value = wfModel.getWorkflowTokenObject('end');
		curX += (config.mode == 'S' ? this.nodetypes.Start.width + hInterval + config.selected.length * (hInterval + this.nodetypes.Manual.width)
					: this.nodetypes.Join.width + hInterval);
		end = create(model, this.nodetypes.End, value, curX, curY);
		if (config.mode == 'P')
			connect(model, join, end);
		
		curX = (config.mode == 'S' ? this.nodetypes.Start.width + hInterval + offsetX
					: this.nodetypes.Start.width + this.nodetypes.Fork.width + 2 * hInterval + offsetX);
		curY = offsetY;
		for (var i=0; i<config.selected.length; i++) {
			value = wfModel.getWorkflowTokenObject('manual');
			value.setAttribute('Name', 'Manual_' + (i + 1));
			value.setAttribute('DisplayName', config.selected[i][config.ppValue]);
			value.setAttribute('Form', formName);

			var extra = DomHelper.getChild(value, 'Extras', true);
			var c = DomHelper.createElement('ActivityParticipants');
			extra.appendChild(c);
			var p = c;
			c = DomHelper.createElement('Participants');
			c.setAttribute('ParticipantDescription', config.title);
			c.setAttribute('ParticipantTypeName', config.title);
			c.setAttribute('ParticipantType', config.type);
			p.appendChild(c);
			p = c;
			c = DomHelper.createElement('Participant');
			c.setAttribute('Name', config.type + '_' + config.selected[i][config.ppKey]);			
			c.setAttribute(config.ppValue, config.selected[i][config.ppValue]);
			p.appendChild(c);
			p = c;
			for (var col in config.selected[i]) {
				c = DomHelper.createElement(col);
				p.appendChild(c);
				c.appendChild(DomHelper.createTextNode(config.selected[i][col]));
			}
			
			manual = create(model, this.nodetypes.Manual, value, curX, curY);
			if (config.mode == 'S') {
				connect(model, prev, manual);
				prev = manual;
				if (i == config.selected.length - 1)
					connect(model, manual, end);
			}
			else {
				connect(model, fork, manual);
				connect(model, manual, join);
			}
			curX += (config.mode == 'S' ? hInterval + this.nodetypes.Manual.width : 0);
			curY += (config.mode == 'S' ? 0 : vInterval + this.nodetypes.Manual.height);
		}
	};
})();